package cmd

import (
	"context"
	"file-system/internal"
	"file-system/internal/handler"
	"fmt"
	"github.com/shiningrush/droplet"
	"github.com/shiningrush/droplet/log"
	"github.com/spf13/cobra"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func NewAgentCommand() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "agent [flags]",
		Short: "AGENT",
		RunE: func(cmd *cobra.Command, args []string) error {
			droplet.Option.Orchestrator = func(mws []droplet.Middleware) []droplet.Middleware {
				var newMws []droplet.Middleware
				// default middleware order: resp_reshape, auto_input, traffic_log
				// We should put err_transform at second to catch all error
				newMws = append(newMws, mws[0], &handler.ErrorTransformMiddleware{})
				newMws = append(newMws, mws[1:]...)
				return newMws
			}

			r := internal.SetUpRouter()
			addr := fmt.Sprintf("%s:%d", "localhost", 8080)
			s := &http.Server{
				Addr:         addr,
				Handler:      r,
				ReadTimeout:  time.Duration(1000) * time.Millisecond,
				WriteTimeout: time.Duration(5000) * time.Millisecond,
			}

			quit := make(chan os.Signal, 1)
			signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

			go func() {
				if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
					log.Error("listen and serv fail: %s", err.Error())
					panic(err.Error())
				}
			}()

			sig := <-quit
			log.Info("The AGENT NIC ENDPOINT API server receive %s and start shutting down", sig.String())

			ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
			defer cancel()

			if err := s.Shutdown(ctx); err != nil {
				log.Errorf("Shutting down server error: %s", err)
			}
			log.Info("The AGENT NIC ENDPOINT API server exited")
			return nil
		},
	}
	workDir := "."
	cmd.PersistentFlags().StringVarP(&workDir, "work-dir", "p", ".", "current work directory")
	return cmd
}
